package fudan.se.lab2.service;

import fudan.se.lab2.controller.request.InviteRequest;
import fudan.se.lab2.domain.Invitation;
import fudan.se.lab2.domain.Meeting;
import fudan.se.lab2.domain.User;
import fudan.se.lab2.exception.InvitationWrongStatusException;
import fudan.se.lab2.repository.InvitationRepository;
import fudan.se.lab2.repository.MeetingRepository;
import fudan.se.lab2.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class InviteService {
    private final UserRepository userRepository;
    private final MeetingRepository meetingRepository;
    private final InvitationRepository invitationRepository;

    @Autowired
    public InviteService(UserRepository userRepository, MeetingRepository meetingRepository, InvitationRepository invitationRepository) {
        this.userRepository = userRepository;
        this.meetingRepository = meetingRepository;
        this.invitationRepository = invitationRepository;
    }

    public Meeting invite(InviteRequest request) {
        String chair = request.getChair();
        String meetingName = request.getMeetingName();
        String[] pcMemberNames = request.getpcMemberNames();
        Invitation newInvitation;

        for (String pcMemberName : pcMemberNames) {
            newInvitation = new Invitation(chair, pcMemberName, meetingName, 0, null);
            invitationRepository.save(newInvitation);
        }
        return meetingRepository.findMeetingByFullName(meetingName);
    }

    public String agreeInvitation(String newPcMember, String meetingName, List<String> topics) {
        Invitation agreeInvitation = invitationRepository.findByToUsernameAndMeetingFullName(newPcMember, meetingName);
        Meeting meeting = meetingRepository.findMeetingByFullName(meetingName);
        List<String> pcMembers = meeting.getPcMembers();
        pcMembers.add(newPcMember);
        meeting.setPcMembers(pcMembers);

        meetingRepository.save(meeting);

        if (agreeInvitation.getStatus() == 0) {
            agreeInvitation.setStatus(1);
            agreeInvitation.setTopics(topics);
            invitationRepository.save(agreeInvitation);
            return "accepted";
        } else {
            throw new InvitationWrongStatusException();
        }
    }

    public String rejectInvitation(String username, String meetingName) {
        Invitation rejectInvitation = invitationRepository.findByToUsernameAndMeetingFullName(username, meetingName);
        if (rejectInvitation.getStatus() == 0) {
            rejectInvitation.setStatus(-1);
            invitationRepository.save(rejectInvitation);
            return "rejected";
        } else {
            throw new InvitationWrongStatusException();
        }
    }

    public List<User> alreadyInvitedUsers(String meetingFullName) {
        Iterable<Invitation> it = invitationRepository.findByMeetingFullName(meetingFullName);
        List<User> alreadyInvitedUsers = new ArrayList<>();
        for (Invitation invitation : it) {
            if (invitation.getStatus() != -1) {
                alreadyInvitedUsers.add(userRepository.findByUsername(invitation.getToUsername()));
            }
        }
        return alreadyInvitedUsers;
    }

    public List<User> notInvitedUsers(String meetingFullName) {
        Iterable<Invitation> it = invitationRepository.findByMeetingFullName(meetingFullName);
        Iterable<User> allUserIt = userRepository.findAll();
        List<User> allUsers = new ArrayList<>();

        for (User next : allUserIt) {
            allUsers.add(next);
        }

        for (Invitation invitation : it) {
            if (invitation.getStatus() != -1) {
                allUsers.remove(userRepository.findByUsername(invitation.getToUsername()));
            }
        }
        return allUsers;
    }

    public List<Invitation> invitationISent(String username) {
        Iterable<Invitation> it = invitationRepository.findByFromUsername(username);
        List<Invitation> invitationISent = new ArrayList<>();
        for (Invitation invitation : it) {
            invitationISent.add(invitation);
        }
        return invitationISent;
    }
}
